feat(semantic): add "did you mean?" suggestions to undefined name errors#19102
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
|
@copilot update conformance snapshot |
Updated in eccd1f3 - conformance snapshots now reflect the new "Did you mean?" suggestions in error messages for undefined exports, private fields, and labels. |
|
@copilot fix lint and format |
Fixed in 3564b6b - addressed all clippy warnings (moved const declarations to function level, used method references instead of closures, used iterator references) and applied formatting. |
There was a problem hiding this comment.
Pull request overview
This PR improves semantic/early-error diagnostics by adding “Did you mean …?” suggestions when a referenced name isn’t found, and centralizes Levenshtein edit-distance utilities for reuse across crates.
Changes:
- Add
best_match/min_edit_distanceutilities tooxc_spanand remove the linter-local copy. - Enhance semantic diagnostics for
undefined_export,private_field_undeclared, andinvalid_label_targetto optionally include a suggestion. - Update coverage snapshots to reflect the new
help:output lines.
Reviewed changes
Copilot reviewed 7 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tasks/coverage/snapshots/parser_typescript.snap | Updates expected TS diagnostic snapshots to include new help: Did you mean ...? lines. |
| tasks/coverage/snapshots/parser_test262.snap | Updates expected Test262 diagnostic snapshots to include new suggestion help lines where applicable. |
| tasks/coverage/snapshots/parser_babel.snap | Updates expected Babel fixture snapshots to include export-name suggestion help. |
| crates/oxc_span/src/lib.rs | Adds the new edit_distance module and re-exports best_match/min_edit_distance. |
| crates/oxc_span/src/edit_distance.rs | Provides the shared Levenshtein implementation and adds unit tests. |
| crates/oxc_semantic/src/diagnostics.rs | Extends select diagnostics to accept an optional suggestion and emit .with_help(...). |
| crates/oxc_semantic/src/checker/javascript.rs | Computes in-scope candidate names/labels on-demand and wires suggestions into diagnostics. |
| crates/oxc_linter/src/utils/mod.rs | Removes the linter-local edit_distance module export. |
| crates/oxc_linter/src/rules/nextjs/no_typos.rs | Switches to importing best_match from oxc_span. |
| crates/oxc_linter/src/rules/eslint/valid_typeof.rs | Switches to importing best_match from oxc_span. |
Merge activity
|
…ors (#19102) ## Improve `undefined_export` and related errors with name suggestions This PR adds helpful "did you mean?" suggestions to errors where names are not found, using Levenshtein distance (threshold=2). ### Example Output **undefined_export with suggestion:** ``` Export 'myVarible' is not defined help: Did you mean 'myVariable'? ``` **private_field_undeclared with suggestion:** ``` Private field '#privateFild' must be declared in an enclosing class help: Did you mean '#privateField'? ``` **invalid_label_target with suggestion:** ``` Use of undefined label help: Did you mean 'outerLoop'? ``` ### Implementation Details - Moved Levenshtein edit distance calculation from `oxc_linter` to `oxc_span` for reuse across crates - Uses a threshold of 2 for edit distance to suggest similar names - Collects available names from appropriate scopes only when errors are found (performance optimization) <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > Improve `undefined_export` and some other errors to include a hint that suggests similar names that are defined </details> <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
f14153d to
655c38f
Compare
### 🚀 Features - 733d6dc parser: Report error on `infer` outside conditional type (#19879) (camc314) - c2a42f6 allocator: Add `Vec::into_bump_slice_mut` (#19895) (overlookmotel) - ee4982b parser: Add `VARIANTS` const to `Kind` via `fieldless_enum!` macro (#19877) (overlookmotel) - b3dceae data_structures: Add `fieldless_enum!` macro (#19876) (overlookmotel) - 12b841e parser: Make all `Kind::is_*` methods `const` (#19874) (overlookmotel) - 25c2e25 estree/tokens: Add function to update tokens in place (#19856) (overlookmotel) - f78e6df parser: Add `mutate_tokens` Cargo feature (#19853) (overlookmotel) - 5036bb6 parser: Report error on `for await` in static blocks (#19844) (camc314) - 42bd431 parser: Report error for missing initializer in using decl (#19824) (camc314) - a2f58e5 parser: Report error for `implements` clause in non-ts files (#19820) (Cameron) - b25228a estree: Add `IS_COMPACT` const to `Formatter` trait (#19787) (overlookmotel) - e2a1b79 estree: Expose buffer and formatter of serializers (#19773) (overlookmotel) - 4699498 data_structures: Add `CodeBuffer::print_strs_array` (#19760) (overlookmotel) - 233f947 estree: `oxc_estree` crate export config and formatter types (#19724) (overlookmotel) - 5937a32 semantic: Introduce `symbol_declarations` method (#19609) (camc314) - ea6b796 parser: Add `LexerConfig::TOKENS_METHOD_IS_STATIC` const (#19683) (overlookmotel) - 655c38f semantic: Add "did you mean?" suggestions to undefined name errors (#19102) (copilot-swe-agent) - 9e11dc6 parser,estree,coverage: Collect tokens in parser and convert to ESTree format (#19497) (camc314) - c4a3677 parser: Report error for initializer in ambient context (#19187) (camc314) ### 🐛 Bug Fixes - abc7e19 codegen: Improve parenthesised checks when printing types (#19880) (camc314) - 017de5d parser: Update error code for type annotation in `for...in` statement (#19882) (camc314) - 7682e5a linter/plugins: Decode escapes in identifier tokens (#19838) (overlookmotel) - 06767ed estree/tokens: Convert `this` tokens in `TSTypeName` (#19815) (overlookmotel) - ef798af parser: Use TS8037 for satisfies expression in JS files diagnostic (#19819) (camc314) - 98ea5c5 parser: Use TS8016 for type assertions in JS files diagnostic (#19818) (camc314) - 1710f56 codegen: Remove double indentation for enum inside namespace (#19775) (Dunqing) - 9e4995c codegen: Print type annotation on `CatchParameter` (#19790) (camc314) - 297b2bb codegen: Wrap `TSConditionalType` in parens when necessary (#19788) (camc314) - cec7878 codegen: Print `definite` property on AccessorProperty (#19786) (camc314) - 6f395cf codegen: Print `definite` property on PropertyDefinition (#19785) (camc314) - b749373 codegen: Correctly parenthesise TSArrayType (#19784) (camc314) - 876dc1b codegen: Print object property `this` param (#19783) (camc314) - 93bb861 formatter: Trim trailing whitespace before breaking line (#19740) (leaysgur) - ed17bbf codegen: Print `override` keyword for method and property definitions (#19753) (Dunqing) - 6a59a76 parser: Improve error recovery for private identifiers in property names (#19710) (Boshen) - 3b96f41 codegen: Print comments in JSX expression containers and spread attributes (#19701) (Boshen) - f5694ce estree/tokens: Reverse field order of `regex` object in tokens (#19679) (overlookmotel) - b2b7a55 estree/tokens: Generate tokens for files with BOM (#19535) (overlookmotel) - 50a7514 estree: Fix tokens for JSX (#19524) (overlookmotel) - a35063e minifier: Preserve side effects for meta property url reads (#19668) (Boshen) - 8ad3430 semantic/jsdoc: Handle even-numbered backtick sequences in JSDoc parsing (#19664) (Boshen) ### ⚡ Performance - 05ccf9f linter/plugins: Transfer tokens via raw transfer (#19893) (overlookmotel) - c1bfdcf estree/tokens: Preallocate sufficient space for tokens JSON (#19851) (overlookmotel) - 4b0611a estree/tokens: Introduce `ESTreeTokenConfig` trait (#19842) (overlookmotel) - 81bab90 estree/tokens: Do not JSON-encode keyword, punctuator, etc tokens (#19814) (overlookmotel) - 6260ddd estree/tokens: Do not JSON-encode `this` identifiers (#19813) (overlookmotel) - b378f4a estree/tokens: Do not JSON-encode JSX identifiers (#19812) (overlookmotel) - 5016d92 estree/tokens: Handle regex tokens separately (#19796) (overlookmotel) - 780a68e estree/tokens: Use strings from AST for identifier tokens (#19744) (overlookmotel) - dc9c2e3 estree: Use `CodeBuffer::print_strs_array` to reduce bounds checks (#19766) (overlookmotel) - 845da35 estree: Use `CodeBuffer::print_indent` (#19727) (overlookmotel) - ec88f6a estree/tokens: Serialize tokens while visiting AST (#19726) (overlookmotel) - bc6507f estree/tokens: Serialize with `ESTree` not `serde` (#19725) (overlookmotel) - ec24859 estree/tokens: Do not branch on presence of override twice (#19721) (overlookmotel) - dac14be estree/tokens: Replace hash map with `Vec` (#19718) (overlookmotel) - b9d2443 estree/tokens: Replace multiple hash sets into a single hash map (#19716) (overlookmotel) - 7233548 parser: Remove branches from `finish_next_inner` (#19695) (overlookmotel) - b5d9845 parser: Remove const generic param from `finish_next_inner` (#19684) (overlookmotel) - 8940f66 estree/tokens: Serialize tokens to compact JSON (#19572) (overlookmotel) - 136e39b parser/tokens: Pre-allocate capacity for tokens (#19543) (overlookmotel) - 6a6513c linter/plugins: Use Oxc tokens in plugins (#19498) (camc314) - b3b2d30 parser: Introduce `ParserConfig` (#19637) (overlookmotel) ### 📚 Documentation - b2b7a64 estree/tokens: Correct comment (#19873) (overlookmotel) - 0399311 estree/tokens: Improve comments (#19836) (overlookmotel) - 1b392de minifier: Add `Function.prototype.toString` assumption (#19758) (sapphi-red) - 75c9cd8 parser: Improve doc comments for `ParserConfig` and `LexerConfig` (#19682) (overlookmotel) - 2fa936f README.md: Map npm package links to npmx.dev (#19666) (Boshen) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
# Oxlint ### 🚀 Features - 2e0e1d0 linter/no-unused-vars: Add experimental fix mode controls (off|suggestion|fix) (#19774) (camc314) - f34f6fa linter: Introduce typeCheck config option (#19764) (camc314) - 694be7d linter: Introduce typeAware as config options (#19614) (camc314) - 655c38f semantic: Add "did you mean?" suggestions to undefined name errors (#19102) (copilot-swe-agent) - e97a57e linter/id-length: Use serde to deserialize rule options (#19636) (camc314) - c4a3677 parser: Report error for initializer in ambient context (#19187) (camc314) - 346045a linter/id-length: Add `checkGeneric` option (#19634) (camc314) ### 🐛 Bug Fixes - 1b7a937 linter: Correct double-comparisons fix with swapped operands (#19846) (camc314) - c308857 linter/consistent_type_imports: Add missing help and notes to diagnostics (#19827) (Daniel Osmond) - 7682e5a linter/plugins: Decode escapes in identifier tokens (#19838) (overlookmotel) - f368fcd linter/consistent_type_assertions: Add missing with_help and with_note to diagnostics (#19826) (Daniel Osmond) - 04e6223 npm: Add `preferUnplugged` for Yarn PnP compatibility (#19829) (Boshen) - 86d5037 linter: Add help text to no-extend-native, no-useless-backreference (#19733) (Anthony Amaro) - 50e8eff linter: Add .with_help() to operator-assignment, no-nonoctal-decimal-escape (#19732) (Anthony Amaro) - 1417bdc linter/no-wrapper-object-types: Add help messages to missing diagnostics (#19771) (Daniel Osmond) - 0838477 linter/ban_ts_comment: Add help and notes to missing diagnostics (#19781) (Daniel Osmond) - e8c77cf linter/adjacent_overload_signatures: Add missing diagnostics (#19780) (Daniel Osmond) - 28834ac linter/ban_types: Add missing help and note to diagnostics (#19782) (Daniel Osmond) - fd938d3 linter/prefer-enum-initializers: Add help messages to missing diagnostics (#19772) (Daniel Osmond) - eb928ee linter/no-dynamic-delete: Add help messages to missing diagnostics (#19768) (Daniel Osmond) - a985666 linter/no-empty-interface: Add help messages to missing diagnostics (#19769) (Daniel Osmond) - 2dc0ceb linter/no-extra-non-null-assertion: Add help messages to missing diagnostics (#19770) (Daniel Osmond) - 95d5d66 linter/no-dupe-keys: Handle `__proto__` proto setters in (#19762) (camc314) - 24ff0db linter/exhaustive-deps: False positive for member expressions in IIFEs (#19751) (Dennis Chen) - 7243a58 linter/no-use-before-define: Honor `ignoreTypeReferences` when value and type name collisions (#19747) (Dimava) - eefd818 linter/explicit-module-boundary-types: Add help messages to missing diagnostics (#19736) (Daniel Osmond) - 0440e9a linter: Add help text to no_control_regex, no_fallthrough, no_param_reassign (#19655) (Anthony Amaro) - e84cb2f react/display-name: Handle merged type+value context symbols (#19608) (camc314) - ce7e253 linter/prefer-object-from-entries: Require exact path match in unicorn helper (#19687) (camc314) - f5694ce estree/tokens: Reverse field order of `regex` object in tokens (#19679) (overlookmotel) - b2b7a55 estree/tokens: Generate tokens for files with BOM (#19535) (overlookmotel) - 0722721 linter/jsx-curly-brace-presence: False positive with prop & mixed quotes (#19674) (camc314) - 3496acd linter: Enhance diagnostic help messages for eslint rules (#19653) (Anthony Amaro) - e384e94 linter: Enhance help diagnostic messages for more eslint rules (#19658) (Anthony Amaro) - a4d5b34 linter: Avoid non-promise catch false positives (#19574) (camc314) - 5706f38 linter: `unicorn/no-array-callback-reference` skip `Effect.*` array-like methods name. (#19633) (Said Atrahouch) ### ⚡ Performance - 05ccf9f linter/plugins: Transfer tokens via raw transfer (#19893) (overlookmotel) - 4b0611a estree/tokens: Introduce `ESTreeTokenConfig` trait (#19842) (overlookmotel) - ec88f6a estree/tokens: Serialize tokens while visiting AST (#19726) (overlookmotel) - d4dcf26 linter/plugins: Remove `typescript` from bundle (#19531) (overlookmotel) - 6a6513c linter/plugins: Use Oxc tokens in plugins (#19498) (camc314) ### 📚 Documentation - d86f59e linter: Improve docs for no-useless-concat, mark as pending fixer. (#19859) (connorshea) - caa091d linter/plugins: Correct doc comments for `initTokens` (#19530) (overlookmotel) - 2fa936f README.md: Map npm package links to npmx.dev (#19666) (Boshen) - dc0ff73 linter/no-useless-constructor: Warn for parameter properties as well (#19638) (Ole Asteo) # Oxfmt ### 🚀 Features - 5141bc2 formatter: Support trailing ignore comments (#19304) (Andreas Lubbe) - 4888a99 oxfmt/lsp: Support other schemes beside `file://` and `untitled://` (#19872) (Sysix) - 14a0181 oxfmt: Support `graphql()` variant for gql-in-js (#19703) (leaysgur) - ca68ea6 oxfmt: Support gql-in-js substitution (#19670) (leaysgur) - 035933c formatter,oxfmt: Support js-in-vue (partially) (#19514) (leaysgur) - 9e11dc6 parser,estree,coverage: Collect tokens in parser and convert to ESTree format (#19497) (camc314) ### 🐛 Bug Fixes - 8e3842d oxfmt: Avoid embedded TSFN crash by returning errors as data (take2) (#19806) (Yuji Sugiura) - 04e6223 npm: Add `preferUnplugged` for Yarn PnP compatibility (#19829) (Boshen) - e540585 oxfmt: Support tailwind sort for CSS/LESS/SCSS (#19803) (leaysgur) - 93bb861 formatter: Trim trailing whitespace before breaking line (#19740) (leaysgur) - b85f97b formatter: Drop blank line between terminal call and first chain member (#19659) (Dunqing) ### ⚡ Performance - b3b2d30 parser: Introduce `ParserConfig` (#19637) (overlookmotel) ### 📚 Documentation - 2fa936f README.md: Map npm package links to npmx.dev (#19666) (Boshen) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Improve
undefined_exportand related errors with name suggestionsThis PR adds helpful "did you mean?" suggestions to errors where names are not found, using Levenshtein distance (threshold=2).
Example Output
undefined_export with suggestion:
private_field_undeclared with suggestion:
invalid_label_target with suggestion:
Implementation Details
oxc_lintertooxc_spanfor reuse across cratesOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.